"""
https://superfastpython.com/asynchronous-generators-in-python/
"""
import sys
import asyncio
import asyncstdlib as a
from PyCmpltrtok.common import sep

if '__main__' == __name__:

    sep('Adapter python >=3.0<3.10')
    # https://stackoverflow.com/questions/9079036/how-do-i-detect-the-python-version-at-runtime
    print(sys.version_info)
    print(type(sys.version_info))
    print(sys.version_info.__class__)
    print(type(sys.version_info).__mro__)
    print(sys.version_info.__class__.__mro__)
    major, minor = sys.version_info[:2]
    if major != 3:
        print('Must use python 3!', file=sys.stderr)
        sys.exit(1)
    elif minor < 10:

        async def anext(ait):
            """
            https://stackoverflow.com/questions/63876013/using-next-on-an-async-generator
            :param ait:
            :return:
            """
            return await ait.__anext__()

    sep('async generator demo')

    async def async_generator(total):
        for i in range(total):
            await asyncio.sleep(0.2)
            n = i + 1
            yield n

    async def run01(times):
        gen = async_generator(4)  # typeerror: object async_generator can't be used in 'await' expression

        for i in range(times):
            n = i + 1
            print(f'{n}: ', end='')

            try:
                awaitable = anext(gen)
                result = await awaitable
            except StopAsyncIteration as ex:
                result = None
                print(f'StopAsyncIteration: {ex} at {n}th iter', file=sys.stderr)
            print(result)

    asyncio.run(run01(6))  # asyncio.run(afunc()) vs task = asyncio.create_task(afunc()) => await task
    print('Call run01 over.')

    sep('async for')

    async def run02():
        async for result in async_generator(5):
            print(result)

    asyncio.run(run02())
    print('Call run02 over.')

    sep('async list comprehension')

    async def run03():
        results = [item async for item in async_generator(6)]
        print(results)

    asyncio.run(run03())
    print('Call run03 over.')

    sep('asyncstdlib enumerate')

    async def run04():
        async for i, item in a.enumerate(async_generator(7), 100):
            n = i + 1
            print(n, item)

    asyncio.run(run04())
    print('Call run04 over.')
